package redemo;

import jmm.SingletonDemo;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 手写自旋锁
 * 自旋锁的本质就是while+CAS
 */
public class SpinLockDemo {
    AtomicReference<Thread> threadrRef = new AtomicReference<>();

    public void lock() {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "\t come in to lock");

        while (!threadrRef.compareAndSet(null, thread)) {

        }
        System.out.println(thread.getName() + "\t success get lock");
    }

    // 解锁的时候必然是取得锁后的线程
    // 否则是非法操作
    public void unlock() {
        Thread thread = Thread.currentThread();
        threadrRef.compareAndSet(thread, null);
        System.out.println(thread.getName() + "\t unlock");
    }

    public static void main(String[] args) {
        SpinLockDemo spinLock = new SpinLockDemo();
        
        new Thread(() -> {
            spinLock.lock();
            try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
            spinLock.unlock();
        }).start();
        
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        
        new Thread(() -> {
            spinLock.lock();
            try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            spinLock.unlock();
        }).start();
    }
}
